Object-oriented programming languages, especially the C++ language, have recently become the standard languages for developing computer software applications. The essence of object-oriented programming is to treat data and the procedures that act upon the data as individual “objects,” each of which is a self-contained entity with an identity and certain characteristics of its own. Each object type is defined by a “class” defined in the source code of the software application. A class specifies how objects of its type behave, such as how they are created, how they can be manipulated, and how they are destroyed. An object of a given class is an “instance” of that class that is created, used, and destroyed during the execution of the software application. The most fundamental notion of object-oriented programming is that classes may be designed by a software developer to represent the fundamental concepts of the “reality” being modeled for the application.
An important aspect of the use of classes in object-oriented programming is the concept of inheritance. A class may be defined as being derived from another class that is referred to as its “base class.” The derived class inherits from the base class in that an object of the derived class automatically gets the data and method members of the base class. The derived class may refine the concept represented by the base class by defining additional data or method members or redefining method members to override those of the base class. Class inheritance provides the powerful intellectual tool of hierarchical ordering for managing the complexity of a program. In this regard, a program can often be organized as a set of trees or directed acyclic graphs of classes. Each node of the tree may be a class derived from another class and may itself be the base class for another derived class.
In many software development projects, a software application is constantly being refined over the life span of the project. Through the development process, concepts concerning various problems and solutions are often revised many times, and the functions and features of the final software application are often quite different from those defined at the beginning of the project. When an object-oriented programming language, such as the C++ language, is used to develop the software, the revisions of concepts would result in the introduction of new classes. In this regard, it is common for program developers to start with a set of broadly defined base classes, and incrementally refine the concepts by designing new classes derived from the existing base classes to provide specific features and functionality. It is also common to design a set of reusable executable modules to provide some common functionality. For instance, the reusable modules may be dynamic-link library (DLL) files that are dynamically linked during the execution of the software product to provide their functionality.
One common problem encountered in developing software applications with object-oriented programming languages is that existing code that creates objects of a base class cannot be reused to create objects of a new class derived from the base class. For instance, in the early stage of software development, a base class may be designed to present general aspects of a user-interface feature, and a new derived class may be designed later to provide specific contents of the user-interface feature. Instructions to create objects of the base class may be included in a program module that has already been tested and is intended to be reusable. The problem is that such a module becomes obsolete when objects of the newly developed derived class are to be created. In order to create objects of the new class, the source listings of the reusable module has to be modified to include the definition of the new class and instructions for creating objects of the new class. In the case of a compilable language, the revised source listing then has to be recompiled to generate a revised module that can create objects of the new class.
Thus, the introduction of a new derived class may require extensive editing and recompilation of existing source listing originally programmed to create objects of the old base classes. This process can be very time consuming and prone to errors, especially when the software project is large and the class hierarchy is complex. As a result, existing object-oriented programming languages do not facilitate incremental development of a software project by gradually replacing base classes with new derived classes.